package com.morpheus.sms;

import java.util.ArrayList;
import java.util.List;

import android.app.AlertDialog;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.OverlayItem;
// congren
public class GooglemapsActivity extends MapActivity {
	private MapView map = null;
	private MyLocationOverlay me = null;
	private MapController mc;
	LocationManager lm;
	private Location currentLocation;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.map);

		map = (MapView) findViewById(R.id.map);
		lm = (LocationManager) getSystemService(LOCATION_SERVICE);

		currentLocation = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);

		mc = map.getController();

		String coordinates[] = { "" + currentLocation.getLatitude(),
				"" + currentLocation.getLongitude() };
		double lat = Double.parseDouble(coordinates[0]);
		double lng = Double.parseDouble(coordinates[1]);

		GeoPoint p = new GeoPoint((int) (lat * 1E6), (int) (lng * 1E6));

		// center to point p, and zoom to level 18 (max is 21)
		mc.animateTo(p);
		mc.setZoom(18);
		map.invalidate();

		Drawable marker = getResources().getDrawable(R.drawable.marker);

		marker.setBounds(0, 0, marker.getIntrinsicWidth(),
				marker.getIntrinsicHeight());

		map.getOverlays().add(new SitesOverlay(marker));

		me = new MyLocationOverlay(this, map);
		map.getOverlays().add(me);

	}

	public class ReverseGeocodeLookupTask extends AsyncTask<Void, Void, String> {
		protected Context applicationContext;

		@Override
		protected void onPreExecute() {
			ProgressDialog.show(applicationContext, "Please wait...",
					"Searching for your chosen location", true);
		}

		@Override
		protected String doInBackground(Void... params) {
			String Address = "";

			if (currentLocation != null) {
				Address = Geocoder.reverseGeocode(currentLocation);
			}

			return Address;
		}

		@Override
		protected void onPostExecute(String result) {

			if (result.toLowerCase().contains("singapore")) {

				String[] splits = result.split("\\s");
				int number = splits.length;

				if (splits[number - 1].equalsIgnoreCase("singapore")) {

					AlertDialog.Builder builder = new AlertDialog.Builder(
							GooglemapsActivity.this);
					builder.setMessage(
							"Your location does not have a postal code.")
							.setCancelable(false)
							.setPositiveButton("Ok, i'm out of here",
									new DialogInterface.OnClickListener() {

										public void onClick(
												DialogInterface dialog, int id) {
											// goes to second activity
											Intent nextactivity = new Intent(
													GooglemapsActivity.this,
													Main.class);
											nextactivity
													.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
											startActivity(nextactivity);
										}
									})
							.setNegativeButton("Let me choose my location",
									new DialogInterface.OnClickListener() {
										public void onClick(
												DialogInterface dialog, int id) {
											// goes to GooglemapsActivity and
											// return
											// location changed
											Intent nextactivity = new Intent(
													GooglemapsActivity.this,
													GooglemapsActivity.class);
											nextactivity
													.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
											startActivity(nextactivity);
										}
									});
					builder.create();
					builder.show();
				} else {

					// result to distill postal code
					String[] result_array = result.split("Singapore");
					final String postal_code = result_array[1];

					// Alert Dialog to confirm booking location
					AlertDialog.Builder builder = new AlertDialog.Builder(
							GooglemapsActivity.this);

					// to be able to display booking location
					builder.setMessage("Your Booking Location is " + result)

							.setCancelable(false)
							.setPositiveButton("Confirm",
									new DialogInterface.OnClickListener() {

										public void onClick(
												DialogInterface dialog, int id) {
											// goes to second activity
											Intent nextactivity = new Intent(
													GooglemapsActivity.this,
													Second.class);
											nextactivity
													.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
											startActivity(nextactivity);

											// book the cab
											String cab = "98890278";
											String book = "Book " + postal_code
													+ " #Pick-up point";
											sendSMS(cab, book);
										}
									})
							.setNeutralButton("Change",
									new DialogInterface.OnClickListener() {
										public void onClick(
												DialogInterface dialog, int id) {
											// goes to GooglemapsActivity
											// and return
											// location changed
											Intent nextactivity = new Intent(
													GooglemapsActivity.this,
													GooglemapsActivity.class);
											nextactivity
													.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
											startActivity(nextactivity);
										}
									})
							.setNegativeButton("Cancel",
									new DialogInterface.OnClickListener() {
										public void onClick(
												DialogInterface dialog, int id) {
											// goes back to main activity
											Intent nextactivity = new Intent(
													GooglemapsActivity.this,
													Main.class);
											nextactivity
													.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
											startActivity(nextactivity);
										}
									});
					builder.create();
					builder.show();
				}
			} else {
				AlertDialog.Builder builder = new AlertDialog.Builder(
						GooglemapsActivity.this);
				builder.setMessage("You are not in Singapore.")
						.setCancelable(false)
						.setPositiveButton("Ok, i'm out of here",
								new DialogInterface.OnClickListener() {

									public void onClick(DialogInterface dialog,
											int id) {
										// goes to second activity
										Intent nextactivity = new Intent(
												GooglemapsActivity.this,
												Main.class);
										nextactivity
												.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
										startActivity(nextactivity);
									}
								})
						.setNegativeButton("Nope, I trust myself",
								new DialogInterface.OnClickListener() {
									public void onClick(DialogInterface dialog,
											int id) {
										// goes to GooglemapsActivity
										// and return
										// location changed
										Intent nextactivity = new Intent(
												GooglemapsActivity.this,
												GooglemapsActivity.class);
										nextactivity
												.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
										startActivity(nextactivity);
									}
								});
				builder.create();
				builder.show();
			}

		}

		// sends sms
		protected void sendSMS(String cab, String book) {
			PendingIntent pi = PendingIntent.getActivity(
					GooglemapsActivity.this, 0, new Intent(
							GooglemapsActivity.this, SmsReceiver.class), 0);
			SmsManager sms = SmsManager.getDefault();
			sms.sendTextMessage(cab, null, book, pi, null);
		}
	}

	@Override
	public void onResume() {
		super.onResume();

		me.enableCompass();
	}

	@Override
	public void onPause() {
		super.onPause();

		me.disableCompass();
	}

	@Override
	protected boolean isRouteDisplayed() {
		return (false);
	}

	private GeoPoint getPoint(double lat, double lon) {
		return (new GeoPoint((int) (lat * 1000000.0), (int) (lon * 1000000.0)));
	}

	private class SitesOverlay extends ItemizedOverlay<OverlayItem> {
		private List<OverlayItem> items = new ArrayList<OverlayItem>();
		private Drawable marker = null;
		private OverlayItem inDrag = null;
		private ImageView dragImage = null;
		private int xDragImageOffset = 0;
		private int yDragImageOffset = 0;
		private int xDragTouchOffset = 0;
		private int yDragTouchOffset = 0;

		public SitesOverlay(Drawable marker) {
			super(marker);
			this.marker = marker;

			dragImage = (ImageView) findViewById(R.id.drag);
			xDragImageOffset = dragImage.getDrawable().getIntrinsicWidth() / 2;
			yDragImageOffset = dragImage.getDrawable().getIntrinsicHeight();

			currentLocation = lm
					.getLastKnownLocation(LocationManager.GPS_PROVIDER);

			String coordinates[] = { "" + currentLocation.getLatitude(),
					"" + currentLocation.getLongitude() };
			double lat = Double.parseDouble(coordinates[0]);
			double lng = Double.parseDouble(coordinates[1]);

			items.add(new OverlayItem(getPoint(lat, lng), null, null));

			populate();
		}

		@Override
		protected OverlayItem createItem(int i) {
			return (items.get(i));
		}

		@Override
		public void draw(Canvas canvas, MapView mapView, boolean shadow) {
			super.draw(canvas, mapView, shadow);

			boundCenterBottom(marker);
		}

		@Override
		public int size() {
			return (items.size());
		}

		@Override
		public boolean onTouchEvent(MotionEvent event, MapView mapView) {
			final int action = event.getAction();
			final int x = (int) event.getX();
			final int y = (int) event.getY();
			boolean result = false;

			if (action == MotionEvent.ACTION_DOWN) {
				for (OverlayItem item : items) {
					Point p = new Point(0, 0);

					map.getProjection().toPixels(item.getPoint(), p);

					if (hitTest(item, marker, x - p.x, y - p.y)) {
						result = true;
						inDrag = item;
						items.remove(inDrag);
						populate();

						xDragTouchOffset = 0;
						yDragTouchOffset = 0;

						setDragImagePosition(p.x, p.y);
						dragImage.setVisibility(View.VISIBLE);

						xDragTouchOffset = x - p.x;
						yDragTouchOffset = y - p.y;

						break;
					}
				}
			} else if (action == MotionEvent.ACTION_MOVE && inDrag != null) {
				setDragImagePosition(x, y);
				result = true;
			} else if (action == MotionEvent.ACTION_UP && inDrag != null) {
				dragImage.setVisibility(View.GONE);

				GeoPoint pt = map.getProjection().fromPixels(
						x - xDragTouchOffset, y - yDragTouchOffset);
				OverlayItem toDrop = new OverlayItem(pt, inDrag.getTitle(),
						inDrag.getSnippet());

				items.add(toDrop);
				populate();

				inDrag = null;
				result = true;

				double latitude = pt.getLatitudeE6() / 1E6;
				double longitude = pt.getLongitudeE6() / 1E6;

				currentLocation.setLatitude(latitude);
				currentLocation.setLongitude(longitude);
				Button b = (Button) findViewById(R.id.button1);
				b.setOnClickListener(new OnClickListener() {

					public void onClick(View v) {

						handleReverseGeocodeClick();

					}
				});

			}

			return (result || super.onTouchEvent(event, mapView));
		}

		private void setDragImagePosition(int x, int y) {
			RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) dragImage
					.getLayoutParams();

			lp.setMargins(x - xDragImageOffset - xDragTouchOffset, y
					- yDragImageOffset - yDragTouchOffset, 0, 0);
			dragImage.setLayoutParams(lp);
		}
	}

	private void handleReverseGeocodeClick() {
		if (this.currentLocation != null) {
			// Kickoff an asynchronous task to fire the reverse geocoding
			// request off to google
			ReverseGeocodeLookupTask task = new ReverseGeocodeLookupTask();
			task.applicationContext = this;
			task.execute();
		} else {

		}
	}
}